# -*- coding: utf-8 -*-
# @Author : zhaochen
# @Date   : 2019/1/23
# @File   : TX03_VATGrowthRate_GZ.py
# @E-mail : zhaochen@bbdservice.com

'''eof
name:增值税增长率
code:TX03_VATGrowthRate_GZ
tableName:
columnName:
groups:税务模块
dependencies:TX_GZ_DSJ
type:常用指标
datasourceType:在线指标
description:
eof'''

import sys
import re
import datetime
import pandas as pd
from collections import OrderedDict


reload(sys)
sys.setdefaultencoding('utf-8')

null_type_list = ['', ' ', None, 'null', 'Null', 'NULL', '/', '-', '--']

last_month_list = [(datetime.datetime.now() - pd.tseries.offsets.DateOffset(months=i)).strftime('%Y%m%d')[:6] \
                    for i in range(1, 30)]

def getTable(table_Name):
    '''
    获取表
    :param x:
    :return:
    '''
    try:
        ic_data = TX_GZ_DSJ['data'].get(table_Name)
        if ic_data is None:
            return [{}]
        else:
            return ic_data if isinstance(ic_data, list) and len(ic_data) > 0 else [{}]
    except:
        return [{}]

def isfloat(x):
    '''
    判断x为float类型
    :param x:
    :return:
    '''
    try:
        if isinstance(float(x), float):
            if str(x) in ['inf', 'infinity', 'INF', 'INFINITY', 'True', 'NAN', 'nan',
                     'False', '-inf', '-INF', '-INFINITY', '-infinity', 'NaN', 'Nan']:
                return False
            else:
                return True
        else:
            return False
    except:
        return False

def formatDate(time):

    import re
    import datetime
    try:
        r = re.compile(r'\D')
        tmp = r.sub('', time)
        if tmp.isdigit():
            date = datetime.datetime.strptime(tmp, '%Y%m%d').strftime('%Y%m%d')
            return date
        else:
            return None
    except:
        return None


def TaxerType():
    try:
        syptSwdjxx = getTable('syptSwdjxx')
        if syptSwdjxx == [{}] or syptSwdjxx is None:
            return None
        else:
            NSRZG_DM = syptSwdjxx[0].get('NSRZG_DM')
            if NSRZG_DM in null_type_list:
                return None
            elif NSRZG_DM not in null_type_list and NSRZG_DM in ['201', '202', '203', '204', '205']:
                return NSRZG_DM
            else:
                return u'其他'
    except:
        return None

# 取应纳税额合计
def getYNSEHJ(table, value):
    try:
        tax_list = OrderedDict()
        for k in last_month_list:
            tax_list.update({k:'None'})
        flag = []
        for i in table:
            ND = i.get('ND')
            YF = i.get('YF')
            #取纳税数据字段
            YNSEHJ = i.get(value)
            if isfloat(ND) and isfloat(YF) and isfloat(YNSEHJ) \
                    and ND not in null_type_list and YF not in null_type_list \
                    and YF in ['01', '02', '03', '04', '05', '06', '07',
                               '08', '09', '10', '11', '12']:
                key = str(ND) + str(YF)
                YNSEHJ = float(YNSEHJ)
                # 优先使用第一个非空数据
                if tax_list.get(key) == 'None':
                    tax_list.update({key: YNSEHJ})
            else:
                flag.append(None)
                continue
        if len(flag) == len(table):
            tax_list = None
        return tax_list
    except:
        return None

#处理小规模纳税人为 若为按季度缴纳均分成按月份缴纳；返回按月缴纳
def monthQuarterData2(tax_list):
    try:
        result = OrderedDict()
        # 为None
        if tax_list is None:
            for k in last_month_list:
                result.update({k: 0.0})
            return result
        # # 全为空
        # if len(set(tax_list.values())) == 1 and 'None' in tax_list.values():
        #     for k in tax_list:
        #         result.update({k: 0})
        #     return result
        # 填充若每月都有数据，则按月 直接返回
        # 若仅有季有数据，则按季进行拆分
        # 若中间有部分月缺失，则使用季的数据进行填充
        for k, v in tax_list.items():
            if k[4:] == '03':
                tmpMonth1 = k[:4] + '01'
                tmpMonth2 = k[:4] + '02'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3:tmp})
                        tax_list.update({tmpMonth2:tmp})
                        tax_list.update({tmpMonth1:tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})

            elif k[4:] == '06' and v != 'None':
                tmpMonth1 = k[:4] + '04'
                tmpMonth2 = k[:4] + '05'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
            elif k[4:] == '09' and v != 'None':
                tmpMonth1 = k[:4] + '07'
                tmpMonth2 = k[:4] + '08'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
            elif k[4:] == '12' and v != 'None':
                tmpMonth1 = k[:4] + '10'
                tmpMonth2 = k[:4] + '11'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
        return tax_list
    except:
        return None

def mergeTaxData():
    try:
        xgm = getTable('syptZzsXgm')
        ybnsr = getTable('syptZzsybnsr')

        if xgm == [{}] and ybnsr == [{}]:
            # 缺失值
            tax_list_sub = None
            return tax_list_sub

        elif xgm == [{}] and ybnsr != [{}]:
            # 用 ybnsr 计算
            tax_list_sub = OrderedDict()
            tax_list = getYNSEHJ(ybnsr, 'YNSEHJ')
            if tax_list != None:
                for k, v in tax_list.items():
                    if v == 'None':
                        tax_list_sub.update({k:0})
                    else:
                        tax_list_sub.update({k:v})
                return tax_list_sub
            else:
                return None

        elif xgm != [{}] and ybnsr == [{}]:
            #用xgm 计算
            tax_list_sub = OrderedDict()
            tax_list = getYNSEHJ(xgm, 'YNSEHJDBNBQ')
            if tax_list != None:
                tax_list = monthQuarterData2(tax_list)
                for k, v in tax_list.items():
                    if v == 'None':
                        tax_list_sub.update({k: 0})
                    else:
                        tax_list_sub.update({k: v})
                return tax_list_sub
            else:
                return None

        elif xgm != [{}] and ybnsr != [{}]:
            #合并 ybnsr 和 xgm 计算 优先使用 ybnsr
            tax_list1 = getYNSEHJ(ybnsr, 'YNSEHJ')
            tax_list2 = getYNSEHJ(xgm, 'YNSEHJDBNBQ')
            if tax_list1 == None and tax_list2 == None:
                return None
            else:
                tax_list_sub = OrderedDict()
                if tax_list1 is None:
                    tax_list2 = monthQuarterData2(tax_list2)
                    for k, v in tax_list2.items():
                        if v == 'None':
                            tax_list_sub.update({k: 0})
                        else:
                            tax_list_sub.update({k: v})
                elif tax_list2 is None:
                    for k, v in tax_list1.items():
                        if v == 'None':
                            tax_list_sub.update({k: 0})
                        else:
                            tax_list_sub.update({k: v})
                else:
                    tax_list2 = monthQuarterData2(tax_list2)
                    for k, v in tax_list1.items():
                        if v == 'None':
                            tmp = tax_list2.get(k)
                            if tmp != 'None':
                                tax_list_sub.update({k: tmp})
                            else:
                                tax_list_sub.update({k: 0})
                        else:
                            tax_list_sub.update({k: v})

                return tax_list_sub
    except:
        return None

#计算月均增值税应纳税额
def MonthAvgFunc(tax):
    try:
        if tax is None:
            return u'缺失值'
        else:
            tax = tax.values()
            #返回合并之后的应纳税额合计
            t1 = tax[0:12]
            t2 = tax[1:13]
            t3 = tax[2:14]
            sum1 = sum(t1 + t2 + t3) / (12.0 * 3.0)

            t1 = tax[12:24]
            t2 = tax[13:25]
            t3 = tax[14:26]
            sum2 = sum(t1 + t2 + t3) / (12.0 * 3.0)
            if sum1 <= 0 or sum2 <= 0:
                return u'缺失值'
            try:
                return round(sum1/sum2 - 1, 4)
            except:
                return u'缺失值'
    except:
        return u'缺失值'

#计算月均增值税应纳税额
def TX03_VATGrowthRate():
    try:
        tax_list = mergeTaxData()
        return MonthAvgFunc(tax=tax_list)
    except:
        return u'缺失值'

result = TX03_VATGrowthRate()